<?php
/**
 *    This file is part of "Liberty Gaming NQ Stats Analyzer".
 *
 *    "Liberty Gaming NQ Stats Analyzer" is free software; you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation; either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    "Liberty Gaming NQ Stats Analyzer" is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
/**
 *    This file has been majorly modified for Nq127 and More Awards!
 *    New coding is made by Johnnei (Johan).
 */


/**
 * Class PCPIN_Parser
 * Main game parser
 * @author Konstantin Reznichak <k.reznichak@pcpin.com>
 * @copyright Copyright &copy; 2007, Konstantin Reznichak
 */
class PCPIN_Parser extends PCPIN_Session {


  /**
   * Game data
   * @var array
   */
  var $game_data=null;

  /**
   * Game clients data (indexed by slot)
   * @var array
   */
  var $clients_slot=null;

  /**
   * Game clients data (indexed by GUID)
   * @var array
   */
  var $clients_guid=null;

  /**
   * Parsed games count
   * @var int
   */
  var $parsed_games=0;

  /**
   * Flag: Set to TRUE if ShutdownGame was executed
   * @var boolean
   */
  var $shutdowngame_executed=false;

  /**
   * Flag: TRUE if game is started
   * @var boolean
   */
  var $game_started=false;

  /**
   * Flag: TRUE after first kill
   * @var boolean
   */
  var $first_kill=false;

  /**
   * Flag: TRUE after first death
   * @var boolean
   */
  var $first_death=false;
  
  /**
	* Award Variables
	* @var int
	*/
	var $Game_Award = null;
  /**
  	* NoQuarter 127 Patch Stater
	*/
	var $nqPatch = false;

  /**
   * Constructor
   * @param   object  &$sessionhandler  Session handler
   */
   
   var $shutdowns = 0;
   var $initgames = 0;
   var $exitlevel = 0;
  function PCPIN_Parser(&$sessionhandler) {
    // Init object
    $this->_s_init($sessionhandler, $this);
  }

	function initAwardArray()
	{
		return array(
	  "jackTheRipper" => array("GUID" => -1, "kills" => -1),//Jack The Ripper Award
	  "grenadier" => array("GUID" => -1, "kills" => -1),	//Grenadier Award
	  "rifleNader" => array("GUID" => -1, "kills" => -1),	//Riflenade Master
	  "drOverdose" => array("GUID" => -1, "kills" => -1),	//Dr. Overdose Award
	  "accuracy" => array("GUID" => -1, "kills" => -1),		//Highest Overall Accuracy
	  "artySpammer" => array("GUID" => -1, "kills" => -1),	//Artillary Spammer
	  "mostHeadshots" => array("GUID" => -1, "kills" => -1),//Most Headshots
	  "bestMedic" => array("GUID" => -1, "kills" => -1), 	//Best Medic
	  "bestEngineer" => array("GUID" => -1, "kills" => -1), //Best Engineer
	  "bestSoldier" => array("GUID" => -1, "kills" => -1), 	//Best Soldier
	  "bestCovertops" => array("GUID" => -1, "kills" => -1),//Best Covert-Ops
	  "bestFieldops" => array("GUID" => -1, "kills" => -1)	//Best Field-Ops
	  );
	}

  /**
   * Parse single log file
   * @param   resource    &$fh    Opened file pointer
   */
  function parseFile(&$fh) {
    // Init vars
    $this->game_data=array();
    $this->clients_slot=array();
    $this->clients_guid=array();
	$this->Game_Award=$this->initAwardArray();
    $this->game_started=false;
    $this->first_kill=false;
    $this->first_death=false;
	$secondShutdown = 0;
	print("Game ");print($this->parsed_games+1);ob_flush(); flush();
    while (false!==$line=fgets($fh)) {
      $line=trim($line);
      if ($line=='') {
        continue;
      }

      // Parse line
      $time=substr($line, 0, strpos($line, ' '));
      $time_len=strlen($time)+1;
      $cmd=substr($line, $time_len);
      $cmd=substr($cmd, 0, strpos($cmd, ':'));
      $cmd_len=strlen($cmd)+1;
      $args=trim(substr($line, $time_len+$cmd_len+1));

      if ($cmd=='WeaponStats')
	  {
		  //Award Vars
		  $player = array (
		  "hits" => 0,
		  "shots" => 0,
		  "kills" => 0, 
		  "deaths" => 0, 
		  "arty" => 0, 
		  "hs" => 0
		  );
       	// Weapon statistics
        $space_pos=strpos($args, ' ');
        $slot=substr($args, 0, $space_pos);
        if (isset($this->clients_slot[$slot])) {
          $stats=$this->parseWeaponStats(substr($args, $space_pos+1));
          // Save weapon stats
          foreach ($stats['weapon_stats'] as $weapon_nr=>$ws)
		  {
            if (!empty($ws))
			{
              $gameclientws=new PCPIN_GameClientWS($this);
              $gameclientws->addRecord($this->clients_slot[$slot]->guid,
                                       $weapon_nr,
                                       $ws['hits'],
                                       $ws['shots'],
                                       $ws['kills'],
                                       $ws['deaths'],
                                       $ws['headshots']
                                       );
				$player['hits'] += $ws['hits'];
				$player['shots']+= $ws['shots'];
				$player['hs']   += $ws['headshots'];
				if($weapon_nr == 12 || $weapon_nr == 13)
				{
					$player['arty'] += $ws['shots'];
				}
				if($ws['kills'] != 0)
				{
					switch($weapon_nr)
					{
					case 0:
						if($ws['kills'] > $this->Game_Award['jackTheRipper']['kills'])
						{
							$this->Game_Award['jackTheRipper']['kills'] = $ws['kills'];
							$this->Game_Award['jackTheRipper']['GUID'] = $this->clients_slot[$slot]->guid;
						}
					break;
					case 9:
						if($ws['kills'] > $this->Game_Award['grenadier']['kills'])
						{
							$this->Game_Award['grenadier']['kills'] = $ws['kills'];
							$this->Game_Award['grenadier']['GUID'] = $this->clients_slot[$slot]->guid;
						}
					break;
					case 17:
						if($ws['kills'] > $this->Game_Award['rifleNader']['kills'])
						{
							$this->Game_Award['rifleNader']['kills'] = $ws['kills'];
							$this->Game_Award['rifleNader']['GUID'] = $this->clients_slot[$slot]->guid;
						}
					break;
					case 30:
						if($ws['kills'] > $this->Game_Award['drOverdose']['kills'])
						{
							$this->Game_Award['drOverdose']['kills'] = $ws['kills'];
							$this->Game_Award['drOverdose']['GUID'] = $this->clients_slot[$slot]->guid;
						}
					break;
					}
				}
			}
			//Compare last variables
			if($player['hs'] > $this->Game_Award['mostHeadshots']['kills'])
			{
				$this->Game_Award['mostHeadshots']['kills'] = $player['hs'];
				$this->Game_Award['mostHeadshots']['GUID'] = $this->clients_slot[$slot]->guid;
			}
			$acc = 0;
			if($player['shots'] != 0)
				$acc = round(($player['hits']/$player['shots'])*100,1);
			if($acc > $this->Game_Award['accuracy']['kills'])
			{
				$this->Game_Award['accuracy']['kills'] = $acc;
				$this->Game_Award['accuracy']['GUID'] = $this->clients_slot[$slot]->guid;
			}
			if($player['arty'] > $this->Game_Award['artySpammer']['kills'])
			{
				$this->Game_Award['artySpammer']['kills'] = $player['arty'];
				$this->Game_Award['artySpammer']['GUID'] = $this->clients_slot[$slot]->guid;
			}
		}
	}
/*
          // Save damage stats
          $gameclientdamage=new PCPIN_GameClientDamage($this);
          $gameclientdamage->addRecord($this->clients_slot[$slot]->guid,
                                       $stats['damage_stats']['damage_given'],
                                       $stats['damage_stats']['damage_received'],
                                       $stats['damage_stats']['team_damage']
                                       );
*/
        continue;
      } elseif (!$this->game_started && $cmd!='InitGame') {
        continue;
      }

      $time=$this->makeSeconds($time);
      switch ($cmd) {

        case 'Item':
          // Player taken some item
          $space_pos=strpos($args, ' ');
          $slot=substr($args, 0, $space_pos);
          if (!isset($this->clients_slot[$slot])) {
            $this->resetGameFlags();
            break;
          }
          $item=substr($args, $space_pos+1);
          if ($item=='team_CTF_redflag' || $item=='team_CTF_blueflag') {
            // Objectives
            $this->clients_slot[$slot]->tookObjectives();
          } elseif ($item=='item_health') {
            $this->clients_slot[$slot]->tookHealth();
          } elseif (substr($item, 0, 16)=='weapon_magicammo') {
            $this->clients_slot[$slot]->tookAmmo();
          }
        break;

        case 'Kill':
          // Player was killed
          $parts=explode(':', $args);
          $parts_a=explode(' ', trim($parts[0]));
          $parts_b=explode(' ', trim($parts[count($parts)-1]));
          $killer_slot=$parts_a[0];
          $victim_slot=$parts_a[1];
          $mod=$parts_b[count($parts_b)-1];
		  if($this->nqPatch)
		  {
			  $name1 = substr($args, strpos($args, ": "),strpos($args," killed ")-strpos($args, ": "));
			  $name2 = substr($args, strpos($args, " killed ")+8,strpos($args, " by MOD_")-strpos($args, " killed ")-8);
			mysql_query("UPDATE `ets_clientname` SET `last_used`='y', `name` = ".'"'.$name1.'"'." WHERE `name_txt` = ".'"'.coloredToPlain($name1).'"'.";");
			mysql_query("UPDATE `ets_clientname` SET `last_used`='y', `name` = ".'"'.$name2.'"'." WHERE `name_txt` = ".'"'.coloredToPlain($name2).'"'.";");
		  }
          if (!isset($this->clients_slot[$victim_slot])) {
            $this->resetGameFlags();
            break;
          }
          if ($killer_slot==$victim_slot) {
            // Suicide
            $this->clients_slot[$killer_slot]->madeSuicide($mod);
            if (!$this->first_death) {
              $this->clients_slot[$killer_slot]->setFirstDeathAward();
              $this->first_death=true;
            }
          } else {
            // A kill
            // Update killer data
            if (isset($this->clients_slot[$killer_slot])) {
              // Killed by player
              $this->clients_slot[$killer_slot]->madeKill($this->clients_slot[$victim_slot]->guid, $this->clients_slot[$victim_slot]->team, $mod);
              $this->clients_slot[$killer_slot]->addBounties(floor($this->clients_slot[$victim_slot]->current_kill_spree/5));
              if (!$this->first_kill && $this->clients_slot[$killer_slot]->team != $this->clients_slot[$victim_slot]->team) {
                $this->clients_slot[$killer_slot]->setFirstKillAward();
                $this->first_kill=true;
              }
              // Update victim
              $this->clients_slot[$victim_slot]->gotKilled($this->clients_slot[$killer_slot]->guid, $this->clients_slot[$killer_slot]->team, $mod);
              if (!$this->first_death && $this->clients_slot[$killer_slot]->team != $this->clients_slot[$victim_slot]->team) {
                $this->clients_slot[$victim_slot]->setFirstDeathAward();
                $this->first_death=true;
              }
            } else {
              // Killed by world
              $this->clients_slot[$victim_slot]->worldDeath($mod);
              if (!$this->first_death) {
                $this->clients_slot[$victim_slot]->setFirstDeathAward();
                $this->first_death=true;
              }
            }
          }
        break;

        case 'Medic_Revive':
          // Player revived someone
          $parts=explode(':', $args);
          $medic_slot=substr($args, 0, strpos($args, ' '));
          $victim_slot=substr($args, strpos($args, ' ')+1);
          if (!isset($this->clients_slot[$medic_slot]) || !isset($this->clients_slot[$victim_slot])) {
            $this->resetGameFlags();
            break;
          }
          $this->clients_slot[$medic_slot]->didRevive($this->clients_slot[$victim_slot]->guid);
        break;

        case 'Health_Pack':
          // Player gave health pack to someone
          $parts=explode(':', $args);
          $medic_slot=substr($args, 0, strpos($args, ' '));
          $victim_slot=substr($args, strpos($args, ' ')+1);
          if (!isset($this->clients_slot[$medic_slot]) || !isset($this->clients_slot[$victim_slot])) {
            $this->resetGameFlags();
            break;
          }
          $this->clients_slot[$medic_slot]->gaveHealthPack($this->clients_slot[$victim_slot]->guid);
        break;

        case 'Ammo_Pack':
          // Player gave ammo pack to someone
          $parts=explode(':', $args);
          $lieut_slot=substr($args, 0, strpos($args, ' '));
          $recv_slot=substr($args, strpos($args, ' ')+1);
          if (!isset($this->clients_slot[$lieut_slot]) || !isset($this->clients_slot[$recv_slot])) {
            $this->resetGameFlags();
            break;
          }
          $this->clients_slot[$lieut_slot]->gaveAmmoPack($this->clients_slot[$recv_slot]->guid);
        break;

        case 'ClientUserinfoChangedGUID':
          // Client data
          $slot=substr($args, 0, strpos($args, ' '));
          $slot_len=strlen($slot)+1;
          $guid=substr($args, $slot_len, 32);
          if (false!==strpos($guid, ' ') && substr($guid, 0, 7)!='OMNIBOT') {
            $guid=substr($guid, 0, strpos($guid, ' '));
          }
          $guid_len=strlen($guid);
          if (!isset($this->clients_guid[$guid])) {
            $this->clients_guid[$guid]=new PCPIN_PlayerData();
          }
		  if($this->nqPatch)
		  {
          	$this->clients_guid[$guid]->ClientUserinfoChanged($guid, substr($args, $slot_len+$guid_len+1), $time);
          	$this->clients_slot[$slot]=&$this->clients_guid[$guid];
		  }
        break;
		
		case 'ClientConnect':
		if(!$this->nqPatch)
			break;
		if(strpos($args, "IP:") != false && strpos($args, "name:") != false)
		{
			$slot=substr($args, 0, strpos($args, ' '));
          $slot_len=strlen($slot)+1;
          $guid=substr($args, $slot_len+4, strpos($args, " name:")-$slot_len-5);
		  $name = substr($args, strpos($args, '"')+1, -1);
          $guid_len=strlen($guid);
          if (!isset($this->clients_guid[$guid])) {
            $this->clients_guid[$guid]=new PCPIN_PlayerData();
          }
		  $this->clients_slot[$slot]=&$this->clients_guid[$guid];
		  $game=new PCPIN_Game($this);
		  $game_id = $game->_db_lastInsertID();
		  $q = mysql_query("UPDATE `ets_clientname` SET `last_used` = 'n' WHERE `guid` = '".$guid."';");
		  $q = mysql_query("INSERT INTO `ets_clientname` (`game_id`,`guid`,`name`,`name_txt`,`last_used`) VALUES (".$game_id.",'".$guid."',".'"'.$name.'","'.$name.'",'."'y');");
		}
		break;

        case 'Dynamite_Plant':
          // Player planted a dynamite near obj
          if (!isset($this->clients_slot[$args])) {
            $this->resetGameFlags();
            break;
          }
          $this->clients_slot[$args]->dynamitePlant();
        break;

        case 'Dynamite_Diffuse':
          // Player diffused a dynamite
          if (!isset($this->clients_slot[$args])) {
            $this->resetGameFlags();
            break;
          }
          $this->clients_slot[$args]->dynamiteDifuse();
        break;

        case 'Repair':
          // Player repaired something
          if (!isset($this->clients_slot[$args])) {
            $this->resetGameFlags();
            break;
          }
          $this->clients_slot[$args]->madeRepair();
        break;

        case 'score':
          // Score
          $slot_start=strpos($args, ' client: ')+9;
          $slot=substr($args, $slot_start, strpos($args, ' ', $slot_start)-$slot_start);
          if (!isset($this->clients_slot[$slot])) {
            $this->resetGameFlags();
            break;
          }
		  if($this->nqPatch){
			$name=substr($args, $slot_start+strlen($slot));
			mysql_query("UPDATE `ets_clientname` SET `last_used` = 'n' WHERE `name_txt` = ".'"'.coloredToPlain($name)."';");
		    mysql_query("UPDATE `ets_clientname` SET `name` = ".'"'.$name.'", `last_used`="y"'." WHERE `name_txt` = ".'"'.coloredToPlain($name).'";');
		   }
          $ping_start=strpos($args, ' ping: ')+7;
          $this->clients_slot[$slot]->setScore(substr($args, 0, strpos($args, ' ')));
          $this->clients_slot[$slot]->setPing(substr($args, $ping_start, strpos($args, ' ', $ping_start)-$ping_start));
        break;


        case 'InitGame':
		$this->initgames++;
			print('<font style="color:#0F0;">.</font>');ob_flush();flush();
          // Match or Warmup started
          $this->resetGameFlags(true!==$this->shutdowngame_executed);
          $this->shutdowngame_executed=false;
          $this->game_started=true;
          $this->game_data=array('timer_start'=>$time);
          $this->parseInitGame($args);
          // Reset players stats
          foreach ($this->clients_guid as $playerdata) {
            $playerdata->resetStats($time);
          }
		  if(strpos($args, "mod_url\\http://shitstorm.org\\mod_version\\1.2.7") !== false)
		  {
		  	$this->nqPatch = true;
		  }
        break;

        case 'ClientDisconnect':
          // Client disconnected
          if (isset($this->clients_slot[$args])) {
            unset($this->clients_slot[$args]);
          }
        break;

        case 'ExitLevel':
		print('<font style="color:#F00;">.</font>');ob_flush();flush();
          // Round ended
          // Stop all team/class timers
		  $this->exitlevel++;
          foreach ($this->clients_guid as $playerdata) {
            $playerdata->toggleTeamClassTimer(-1, -1, $time);
          }
          // Store game data into database
          $game=new PCPIN_Game($this);
          $gameclient=new PCPIN_GameClient($this);
          $clientname=new PCPIN_ClientName($this);
          $gameclientteamclass=new PCPIN_GameClientTeamClass($this);
          $gameclientkill=new PCPIN_GameClientKill($this);
          $gameclientdeath=new PCPIN_GameClientDeath($this);
          $gameclientsuicide=new PCPIN_GameClientSuicide($this);
          $gameclientrevive=new PCPIN_GameClientRevive($this);
          $gameclienthealth=new PCPIN_GameClientHealth($this);
          $gameclientammo=new PCPIN_GameClientAmmo($this);
          $gameclientmisc=new PCPIN_GameClientMisc($this);
		  $gameclientawards=new PCPIN_GameClientAwards($this);

          $game->addGame($this->game_data['mapname'], $time-$this->game_data['timer_start'], count($this->clients_guid), 0);
          $game_id=$game->_db_lastInsertID();
          // Store game clients
          $active_players_count=0;
          foreach ($this->clients_guid as $playerdata) {
            if (isset($playerdata->team_class_timers[1]) || isset($playerdata->team_class_timers[2])) {
              $active_players_count++;
            }
            // Used names
            foreach ($playerdata->used_names as $name) {
              $clientname->addNameRecord($game_id, $playerdata->guid, $name);
            }
            // Teams/classes and times
            $time_axis=0;
            $time_allies=0;
            $time_spectator=0;
            foreach ($playerdata->team_class_timers as $team=>$timers) {
              foreach ($timers as $class=>$time) {
                if ($time>0) {
                  $gameclientteamclass->addRecord($game_id, $playerdata->guid, $team, $class, $time);
                  if ($team==1) {
                    // AXIS
                    $time_axis+=$time;
                  } elseif ($team==2) {
                    // ALLIES
                    $time_allies+=$time;
                  } else {
                    // SPECTATOR
                    $time_spectator+=$time;
                  }
                }
              }
            }
            // Kills made by client
            $killed_enemies=0;
            $killed_teammates=0;
            foreach ($playerdata->killed_enemies as $team=>$classes) {
              foreach ($classes as $class=>$victims) {
                foreach ($victims as $guid=>$kills) {
                  foreach ($kills as $mod=>$count) {
                    $gameclientkill->addRecord($game_id, $playerdata->guid, $class, $guid, $team, 'y', $mod, $count);
                    $killed_enemies+=$count;
                  }
                }
              }
            }
            foreach ($playerdata->killed_teammates as $team=>$classes) {
              foreach ($classes as $class=>$victims) {
                foreach ($victims as $guid=>$kills) {
                  foreach ($kills as $mod=>$count) {
                    $gameclientkill->addRecord($game_id, $playerdata->guid, $class, $guid, $team, 'n', $mod, $count);
                    $killed_teammates+=$count;
                  }
                }
              }
            }
            // Deaths
            $killed_by_enemies_count=0;
            $killed_by_teammates_count=0;
            $killed_by_world_count=0;
            $suicides_count=0;
            foreach ($playerdata->killed_by_enemies as $team=>$deaths) {
              foreach ($deaths as $guid=>$kills) {
                foreach ($kills as $mod=>$count) {
                  $gameclientdeath->addRecord($game_id, $playerdata->guid, $guid, $team, 'y', $mod, $count);
                  $killed_by_enemies_count+=$count;
                }
              }
            }
            foreach ($playerdata->killed_by_teammates as $team=>$deaths) {
              foreach ($deaths as $guid=>$kills) {
                foreach ($kills as $mod=>$count) {
                  $gameclientdeath->addRecord($game_id, $playerdata->guid, $guid, $team, 'n', $mod, $count);
                  $killed_by_teammates_count+=$count;
                }
              }
            }
            // World deaths
            foreach ($playerdata->world_deaths as $team=>$deaths) {
              foreach ($deaths as $mod=>$count) {
                $gameclientdeath->addRecord($game_id, $playerdata->guid, '<world>', $team, 'w', $mod, $count);
                $killed_by_world_count+=$count;
              }
            }
            // Suicides
            foreach ($playerdata->suicides as $team=>$suicides) {
              foreach ($suicides as $mod=>$count) {
                $gameclientsuicide->addRecord($game_id, $playerdata->guid, $team, $mod, $count);
                $suicides_count+=$count;
              }
            }
            // Revives
            $revives_count=0;
            foreach ($playerdata->revives as $team=>$victims) {
              foreach ($victims as $guid=>$count) {
                $gameclientrevive->addRecord($game_id, $playerdata->guid, $guid, $team, $count);
                $revives_count+=$count;
              }
            }
            // Health given
            $health_given_count=0;
            foreach ($playerdata->health_given as $team=>$victims) {
              foreach ($victims as $guid=>$count) {
                $gameclienthealth->addRecord($game_id, $playerdata->guid, $guid, $team, $count);
                $health_given_count+=$count;
              }
            }
            // Ammo given
            $ammo_given_count=0;
            foreach ($playerdata->ammo_given as $team=>$victims) {
              foreach ($victims as $guid=>$count) {
                $gameclientammo->addRecord($game_id, $playerdata->guid, $guid, $team, $count);
                $ammo_given_count+=$count;
              }
            }
            // Misc data
            $dynamite_plant_count=0;
            $dynamite_diffuse_count=0;
            $repairs_count=0;
            $disguises_count=0;
            $objectives_taken_count=0;
            $teams=array(1, 2);
            foreach ($teams as $team) {
              if (   !empty($playerdata->dynamite_plant[$team])
                  || !empty($playerdata->dynamite_diffuse[$team])
                  || !empty($playerdata->repairs[$team])
                  || !empty($playerdata->disguises[$team])
                  || !empty($playerdata->objectives_taken[$team])
                  ) {
                $gameclientmisc->addRecord($game_id,
                                           $playerdata->guid,
                                           $team,
                                           !empty($playerdata->dynamite_plant[$team])? $playerdata->dynamite_plant[$team] : 0,
                                           !empty($playerdata->dynamite_diffuse[$team])? $playerdata->dynamite_diffuse[$team] : 0,
                                           !empty($playerdata->repairs[$team])? $playerdata->repairs[$team] : 0,
                                           !empty($playerdata->disguises[$team])? $playerdata->disguises[$team] : 0,
                                           !empty($playerdata->objectives_taken[$team])? $playerdata->objectives_taken[$team] : 0
                                           );
                $dynamite_plant_count+=!empty($playerdata->dynamite_plant[$team])? $playerdata->dynamite_plant[$team] : 0;
                $dynamite_diffuse_count+=!empty($playerdata->dynamite_diffuse[$team])? $playerdata->dynamite_diffuse[$team] : 0;
                $repairs_count+=!empty($playerdata->repairs[$team])? $playerdata->repairs[$team] : 0;
                $disguises_count+=!empty($playerdata->disguises[$team])? $playerdata->disguises[$team] : 0;
                $objectives_taken_count+=!empty($playerdata->objectives_taken[$team])? $playerdata->objectives_taken[$team] : 0;
              }
            }
            // Kill sprees
            $playerdata->killSpreeEnded();
            // Death sprees
            $playerdata->deathSpreeEnded();
            // Store game client
            $gameclient->addClient($game_id,
                                   $playerdata->guid,
                                   $time_axis,
                                   $time_allies,
                                   $time_spectator,
                                   $killed_enemies,
                                   $killed_teammates,
                                   $killed_by_enemies_count,
                                   $killed_by_teammates_count,
                                   $killed_by_world_count,
                                   $suicides_count,
                                   $playerdata->score,
                                   $playerdata->ping,
                                   $revives_count,
                                   $health_given_count,
                                   $ammo_given_count,
                                   $playerdata->health_taken_count,
                                   $playerdata->ammo_taken_count,
                                   $dynamite_plant_count,
                                   $dynamite_diffuse_count,
                                   $repairs_count,
                                   $disguises_count,
                                   $objectives_taken_count,
                                   $playerdata->first_kill,
                                   $playerdata->first_death,
                                   $playerdata->kill_sprees,
                                   $playerdata->longest_kill_spree,
                                   $playerdata->death_sprees,
                                   $playerdata->longest_death_spree,
                                   $playerdata->bounties,
                                   $playerdata->engineer_kills,
                                   $playerdata->fieldops_kills,
                                   $playerdata->covertops_kills
                                   );

          }
          // Store active game players count
          if ($active_players_count>0) {
            $game->_db_updateRow($game_id, 'id', array('players'=>$active_players_count));
          }
		  //Retrieve Last Data for Awards
		  $temp=$gameclient->getBestMedic($game_id);
		  if(!empty($temp['GUID_Key']))
		  {
			  $this->Game_Award['bestMedic']['GUID']=$temp['GUID_Key'];
		 	  $this->Game_Award['bestMedic']['kills']=$temp['ClassScore'];
		  }
		  $temp=$gameclient->getBestEngineer($game_id);
		  if(!empty($temp['GUID_Key']))
		  {
			  $this->Game_Award['bestEngineer']['GUID']=$temp['GUID_Key'];
		 	  $this->Game_Award['bestEngineer']['kills']=$temp['ClassScore'];
		  }
		  $temp=$gameclientkill->getBestModKiller('MOD_PANZERFAUST,MOD_BAZOOKA,MOD_VENOM,MOD_MG42,MOD_MOBILE_MG42,MOD_BROWNING,MOD_MOBILE_BROWNING,MOD_FLAMETHROWER,MOD_MAPMORTAR,MOD_MAPMORTAR_SPLASH,MOD_MORTAR', $game_id);
		  if(!empty($temp['GUID_Key']))
		  {
			  $this->Game_Award['bestSoldier']['GUID']=$temp['GUID_Key'];
		 	  $this->Game_Award['bestSoldier']['kills']=$temp['Count'];
		  }
		  $temp=$gameclient->getBestCovertOp($game_id);
		  if(!empty($temp['GUID_Key']))
		  {
			  $this->Game_Award['bestCovertops']['GUID']=$temp['GUID_Key'];
		 	  $this->Game_Award['bestCovertops']['kills']=$temp['ClassScore'];
		  }
		  $temp=$gameclient->getBestfieldOp($game_id);
		  if(!empty($temp['GUID_Key']))
		  {
			  $this->Game_Award['bestFieldops']['GUID']=$temp['GUID_Key'];
		 	  $this->Game_Award['bestFieldops']['kills']=$temp['ClassScore'];
		  }
		  // Store Award Data
		  $gameclientawards->addRecord($game_id, $this->Game_Award);
          // Stop the game
          $this->resetGameFlags();
          // Increase parsed games counter
		  print("Done<br/>");
          $this->parsed_games++;
		  	print("Game ");
			print($this->parsed_games+1);
		  ob_flush();
		  flush();
        break;

        case 'ShutdownGame':
          // Reset game flags
          $this->resetGameFlags(false);
          $this->shutdowngame_executed=true;
		  $this->shutdowns++;
		  print('<font style="color:#0CF;">.</font>');ob_flush();flush();
		  if($secondShutdown == 2)
		  {
		  	print("Done<br/>");
          	$this->parsed_games++;
		  	print("Game ");
			print($this->parsed_games+1);
			$secondShutdown = 0;
		  	ob_flush();
		  	flush();
		  }
		  $secondShutdown++;
        break;

      }
    }
	print("Not in this file - File Parsed<br/>");
	ob_flush();
	flush();
  }


  /**
   * Reset game flags
   * @param   boolean   $reset_slots    Optional. Default: TRUE. If TRUE, then player slots will be also deleted.
   */
  function resetGameFlags($reset_slots=true) {
    // Stop the game
    $this->game_started=false;
    // Reset "first kill" and "first death" flags
    $this->first_kill=false;
    $this->first_death=false;
	$this->nqPatch = false;
    if ($reset_slots) {
      // Reset slots
      $this->clients_slot=array();
      $this->clients_guid=array();
	  $this->Game_Award=$this->initAwardArray();
    }
  }


  /**
   * Parse InitGame record
   * @param   string    $args   InitGame arguments
   */
  function parseInitGame($args) {
    $pairs=explode('\\', ltrim($args, '\\'));
    $pairs_num=count($pairs);
    for ($i=0; $i<$pairs_num; $i+=2) {
      $this->game_data[$pairs[$i]]=$pairs[$i+1];
    }
  }


  /**
   * Parse weaponstats record
   * @param   string    $ws   WS line
   * @return  array
   */
  function parseWeaponStats($ws) {
    $stats=array('weapon_stats'=>array(),
                 'damage_stats'=>array(),
                 'skillpoints'=>array(),
                 );
    $parts=explode(' ', $ws);
    array_shift($parts);
    $weapon_bits=getBits(array_shift($parts));
    if (!empty($weapon_bits)) {
      // There are some weaponstats
      foreach ($weapon_bits as $weapon_nr) {
        $stats['weapon_stats'][$weapon_nr]=array('hits'=>array_shift($parts),
                                                 'shots'=>array_shift($parts),
                                                 'kills'=>array_shift($parts),
                                                 'deaths'=>array_shift($parts),
                                                 'headshots'=>array_shift($parts)
                                                 );
      }
    }
/*
    if (count($parts)>=3) {
      // Damage stats
      $stats['damage_stats']=array('damage_given'=>array_shift($parts),
                                   'damage_received'=>array_shift($parts),
                                   'team_damage'=>array_shift($parts)
                                   );
    }
    if (!empty($parts)) {
      // Parse skillpoints
      $stats['skillpoints']=array();
      $skill_bits=getBits(array_shift($parts));
      foreach ($skill_bits as $skill_nr) {
        $stats['skillpoints'][$skill_nr]=array_shift($parts);
      }
    }
*/
    return $stats;
  }

  /**
   * Convert time from format HH:MM:SS into seconds
   * @param   string    $time   Timestamp in format HH:MM:SS
   * @return int
   */
  function makeSeconds($time) {
    $seconds=0;
    $parts=explode(':', trim($time));
    foreach ($parts as $part) {
      $seconds=$seconds*60+$part;
    }
    return $seconds;
  }

}
?>